home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 July: Mac OS SDK / Dev.CD Jul 96 SDK / Dev.CD Jul 96 SDK2.toast / Development Kits (Disc 2) / QuickDraw GX / Programming Stuff / Sample Code / Printing Samples / Printer Drivers… / ImageWriterLQ (alt. rdip) / OldAPIMessageIntf.c < prev    next >
Encoding:
Text File  |  1995-04-10  |  19.6 KB  |  718 lines  |  [TEXT/MPS ]

  1. /*---------------------------------------------------------------------------
  2. FILENAME
  3.     OldAPIMessageIntf.c
  4.  
  5. DESCRIPTION
  6.     This module contains the routines which implement the old API messages
  7.     that the ImageWriter LQ driver overrides.  Much of the logic in this
  8.     module was gleaned from the original ImageWriter LQ driver, and so
  9.     some of the calculations may seem a little strange.  In order to maintain
  10.     compatibility with the old driver's logic, we must preserve much of the
  11.     old logic.
  12.         
  13. COPYRIGHT
  14.      Copyright Apple Computer, Inc. 1992-1994
  15.      All rights reserved. 
  16.         
  17. INTERFACE ROUTINES:
  18.  
  19.     SD_PrValidate
  20.     SD_ConvertPrintRecordTo
  21.     SD_ConvertPrintRecordFrom
  22.  
  23.     12/20/93 - dmh - Sync'd with the shipping 1.0b3 GX driver.
  24.      8/28/94 - dmh - Sync'd with the shipping 1.0.1 GX driver.
  25.  
  26. -------------------------------------------------------------------------------- */
  27.  
  28. // Include the standard Mac header files 
  29. #include "MacIncludes.h"
  30.  
  31. // Include the new QuickDraw GX graphics header files 
  32. #include <graphics routines.h>
  33. #include <graphics libraries.h>
  34. #include <math routines.h>
  35.  
  36. // Include the required Printing Manager header files 
  37. #include <PrintingManager.h>
  38. #include <PrintingMessages.h>
  39. #include <PrintingDrivers.h>
  40. #include <Collections.h>
  41. #include <Messages.h>
  42. #include <PrintingResTypes.h>
  43. #include <PrintingErrors.h>
  44. #include <GXExceptions.h>
  45.  
  46. // Include the internal driver constants and types used by this module 
  47. #include "Resources.h"
  48. #include "OldAPIMessageIntf.h"
  49.  
  50.  
  51. /***************************************************************************************
  52. *                                         INTERNAL ROUTINES                                                    *
  53. ***************************************************************************************/
  54.  
  55.  
  56. /****************************************************************************************
  57.  
  58.                             OldLQ_CiMetrics
  59.                             
  60.     function:
  61.                 This function takes an old style print record and massages its fields in 
  62.                 a manner equivalent to the old style LQ driver.  This logic is basically
  63.                 lifted from the old LQ driver.
  64.                 
  65.     parameters:                
  66.                 hPrint        target print record whose fields are to be updated
  67.  
  68.     returns:
  69.                 none
  70.     
  71. ****************************************************************************************/
  72. void OldLQ_CiMetrics(THPrint    hPrint)
  73. {
  74.     TPPrint    pPrint = *hPrint;
  75.     short        dhPage;
  76.     short        dvPage;
  77.     short        dhPaper;
  78.     short        dvPaper;
  79.     short        hOff;
  80.     short        vOff;
  81.     short        cPlaten;
  82.     short        gap;
  83.     short        scanBits;
  84.     short        maxH;
  85.     short        wDev;
  86.  
  87.     cPlaten = kPlaten8;
  88.     if ( pPrint->prStl.iPageH > (9 * kMysticPaperFract) ) 
  89.     {
  90.         cPlaten = kPlaten15;                     // platen width in half inches
  91.     }
  92.  
  93.     wDev = pPrint->printX[1];
  94.     pPrint->prInfo.iDev = 0;                     // Use screen device for lo res or fake hi res
  95.     if ( !TestBit(wDev, kResSetBit) )         // not fResSet
  96.     {                                     
  97.         pPrint->prInfo.iVRes = 72;
  98.         pPrint->prInfo.iHRes = 72;
  99.     }                                         
  100.     else
  101.     if ( pPrint->prInfo.iVRes == 216 )    // Real HiRes
  102.     {
  103.         wDev |= kHighResBit;                    //    force "hi res"
  104.         wDev &= ~k66PercentReducBit;         // clear 66% Reduction off
  105.         wDev &= ~k33PercentReducBit;         // clear 33% Reduction off
  106.         pPrint->printX[1] = wDev;
  107.     }
  108.  
  109.     // Calculate rPaper height in Y
  110.     dvPaper = (pPrint->prStl.iPageV * pPrint->prInfo.iVRes) / kMysticPaperFract;
  111.     
  112.     // Calculate rPage height in Y
  113.     gap = (60 * pPrint->prInfo.iVRes) / kMysticPaperFract;
  114.             
  115.     if ( TestBit(wDev, kScrollBit) )
  116.     {
  117.         gap = 0;
  118.     }
  119.             
  120.     // force page height to be an integral number of head scans
  121.     dvPage = (( dvPaper - gap ) / 24) * 24;
  122.         
  123.     // Calculate rPaper width in dots
  124.     dhPaper = (pPrint->prStl.iPageH * pPrint->prInfo.iHRes) / kMysticPaperFract;
  125.  
  126.     // Calculate max width in dots
  127.         
  128.     maxH = ( cPlaten * pPrint->prInfo.iHRes ) >> 1;
  129.     if (maxH > dhPaper)
  130.     {
  131.         maxH = dhPaper;
  132.     }
  133.     scanBits = ( maxH >> 4 ) << 4;    // force to word boundary
  134.  
  135.     if ( TestBit(pPrint->prStl.wDev, kPortraitBit) )    //    Portrait orientation
  136.     {
  137.         dhPage = scanBits;
  138.     }
  139.     else    //    Landscape orientation: switch height and width
  140.     {
  141.         dhPage = dvPage;
  142.         dvPage = scanBits;
  143.     }
  144.  
  145.     SetRect(&pPrint->prInfo.rPage, 0, 0, dhPage, dvPage);
  146.  
  147.     // Calculate rPaper offsets, & set rPaper
  148.     
  149.     if ( TestBit(pPrint->prStl.wDev, kPortraitBit) )    //    Portrait orientation
  150.     {
  151.         hOff = (dhPage - dhPaper) >> 1; // Note: Negative
  152.         vOff = -gap;
  153.     }
  154.     else    //    Landscape orientation: switch height and width
  155.     {
  156.         short        iTemp;
  157.  
  158.         iTemp = dhPaper;
  159.         dhPaper = dvPaper;
  160.         dvPaper = iTemp;
  161.  
  162.         hOff = - gap;
  163.         vOff = (dvPage - dvPaper) >> 1;
  164.     }
  165.     SetRect(&pPrint->rPaper, hOff, vOff, dhPaper + hOff, dvPaper + vOff);
  166.         
  167.     // Calculate rPage height in dots, & set rPage
  168.     //If 66% reduction, triple both rectangles: ( Page and Paper )
  169.  
  170.     if ( TestBit(wDev, k66PercentReducBit) )    //    66% reduction selected
  171.     {
  172.         pPrint->prInfo.rPage.right *= 3;
  173.         pPrint->prInfo.rPage.bottom *= 3;
  174.         
  175.         pPrint->rPaper.top *= 3;
  176.         pPrint->rPaper.left *= 3;
  177.         pPrint->rPaper.right *= 3;
  178.         pPrint->rPaper.bottom *= 3;
  179.     }
  180.  
  181.     // If 33% reduction, scale both rectangles: ( Page and Paper )
  182.     if ( TestBit(wDev, k33PercentReducBit) )    //    33% reduction selected
  183.     {
  184.         pPrint->prInfo.rPage.right = FixRound( FixMul( lScale, (pPrint->prInfo.rPage.right << 16) ));
  185.         pPrint->prInfo.rPage.bottom = FixRound( FixMul( lScale, (pPrint->prInfo.rPage.bottom << 16) ));
  186.         
  187.         pPrint->rPaper.top = FixRound( FixMul( lScale, (pPrint->rPaper.top << 16) ));
  188.         pPrint->rPaper.left = FixRound( FixMul( lScale, (pPrint->rPaper.left << 16) ));
  189.         pPrint->rPaper.right = FixRound( FixMul( lScale, (pPrint->rPaper.right << 16) ));
  190.         pPrint->rPaper.bottom = FixRound( FixMul( lScale, (pPrint->rPaper.bottom << 16) ));
  191.     }
  192.                 
  193.     if ( TestBit(wDev, kDraftBit) )    //    Draft bits selected
  194.     {
  195.         pPrint->prJob.bJDocLoop = bDraftLoop;
  196.     }
  197.  
  198.     // Copy WDEV field back to old position for apps that read these flags
  199.     
  200.     if ( TestBit(pPrint->prStl.wDev, kPortraitBit) )
  201.     {
  202.         wDev |= kPortraitBit;
  203.     }
  204.     else
  205.     {
  206.         wDev &= ~kPortraitBit;
  207.     }
  208.     
  209.     pPrint->printX[1] = wDev;
  210.     pPrint->prStl.wDev = wDev;
  211. }
  212. /* OldLQ_CiMetrics */
  213.  
  214.  
  215. /****************************************************************************************
  216.  
  217.                             OldLQ_CiXMetrics
  218.                             
  219.     function:
  220.                 This function takes an old style print record and massages the PrInfoPT and
  221.                 PrXInfo fields in a manner equivalent to the old style LQ driver.  This logic 
  222.                 is basically lifted from the old LQ driver.
  223.                 
  224.     parameters:                
  225.                 hPrint        target print record whose fields are to be updated
  226.  
  227.     returns:
  228.                 none
  229.     
  230. ****************************************************************************************/
  231. void OldLQ_CiXMetrics(THPrint    hPrint)
  232. {
  233.     TPPrint    pPrint = *hPrint;
  234.     short        iScans;
  235.     short        iDevExtra;
  236.  
  237.     pPrint->prInfoPT = pPrint->prInfo; // Start with a straight copy
  238.  
  239.     pPrint->prXInfo.bPatScale = 0;
  240.  
  241.     if ( !TestBit(pPrint->prStl.wDev, kPortraitBit) )    //    Landscape mode
  242.     {
  243.         pPrint->prJob.bJDocLoop = bSpoolLoop; // Force spooling for landscape
  244.     }
  245.  
  246.     if ( TestBit(pPrint->printX[1], k66PercentReducBit) || TestBit(pPrint->printX[1], k33PercentReducBit) ) // 33% or 66% reduction
  247.     {
  248.         pPrint->printX[1] &= ~kHighResBit;        //    Clear the high-res bit
  249.         
  250.         if ( TestBit(pPrint->printX[1], k33PercentReducBit) )    // If 33% Reduction ONLY
  251.         {
  252.             pPrint->prXInfo.bPatScale = 2;         // Pattern double
  253.             
  254.             // SCALE 2X FOR 33% REDUCTION CASE
  255.             pPrint->prInfoPT.rPage.right <<= 1;
  256.             pPrint->prInfoPT.rPage.bottom <<= 1;
  257.         }
  258.     }
  259.  
  260.     if ( TestBit(pPrint->printX[1], kHighResBit) )    //    High resolution; triple everything
  261.     {
  262.         if ( !TestBit(pPrint->printX[1], kResSetBit) )    //    App hasn't set imaging resolution
  263.         {
  264.             pPrint->prInfoPT.iHRes *= 3;
  265.             pPrint->prInfoPT.iVRes *= 3;
  266.             pPrint->prInfoPT.rPage.right *= 3;
  267.             pPrint->prInfoPT.rPage.bottom *= 3;
  268.         }
  269.         
  270.         pPrint->prXInfo.bPatScale = 3;         // Pattern triple ** NOT VALID QD ** Intercept in PrBand
  271.         pPrint->prInfoPT.iDev = 0xFD00;         // For QD's char spacing adjustment
  272.     }
  273.  
  274.     if ( TestBit(pPrint->prStl.wDev, kPortraitBit) )    //    Portrait mode
  275.     {
  276.         pPrint->prXInfo.iBandH = pPrint->prInfoPT.rPage.right;
  277.         pPrint->prXInfo.iBandV = 48;                                     // i8xBandScans = 24 * 2
  278.         iScans = pPrint->prInfoPT.rPage.bottom;
  279.         pPrint->prXInfo.scan = scanTop2Bottom;
  280.         iDevExtra = pPrint->prXInfo.iBandH;
  281.     }
  282.     else    //    Landscape mode
  283.     {
  284.         pPrint->prXInfo.iBandH = 48;                                     // i8xBandScans = 24 * 2;
  285.         pPrint->prXInfo.iBandV = pPrint->prInfoPT.rPage.bottom;
  286.         iScans = pPrint->prInfoPT.rPage.right;
  287.         pPrint->prXInfo.scan = scanLeft2Right;
  288.         iDevExtra = pPrint->prXInfo.iBandV;
  289.     }
  290.  
  291.     pPrint->prXInfo.iRowBytes = pPrint->prXInfo.iBandH >> 3;     // Must be even!
  292.     pPrint->prXInfo.iBands = ( iScans + 48 - 1 ) / 48;
  293.     
  294.     // Size a scan work buffer
  295.     pPrint->prXInfo.iDevBytes = ( pPrint->prXInfo.iRowBytes * pPrint->prXInfo.iBandV ) + ( iDevExtra * 3 ); 
  296.  
  297.     // Copy WDEV field back to old position for apps that read these flags
  298.     pPrint->prStl.wDev = pPrint->printX[1];
  299. }
  300. /* OldLQ_CiXMetrics */
  301.  
  302.  
  303. /****************************************************************************************
  304.  
  305.                             UpdatePrintRecord
  306.                             
  307.     function:
  308.                 This function updates the print record based upon the application's
  309.                 calls to PrGeneral.
  310.                 
  311.     parameters:                
  312.                 hPrint            print record to update
  313.                 
  314.     returns:
  315.                 none
  316.     
  317. ****************************************************************************************/
  318. void UpdatePrintRecord(THPrint hPrint)
  319. {
  320.     // emulate the old metric calculations        
  321.     OldLQ_CiMetrics(hPrint);
  322.     OldLQ_CiXMetrics(hPrint);
  323. }
  324. /* UpdatePrintRecord */
  325.  
  326.  
  327.  
  328. /***************************************************************************************
  329. *                                         INTERFACE ROUTINES                                                     *
  330. ***************************************************************************************/
  331.  
  332. /****************************************************************************************
  333.  
  334.                             SD_PrValidate
  335.                             
  336.     function:
  337.                 This function validates the print record.  If the passed-in print record contains
  338.                 valid information (see below), then it's updated based upon the application's
  339.                 calls to PrGeneral and the return code is true.
  340.                 Otherwise, the print record is defaulted (with PrintDefault), and the 
  341.                 return value is false.
  342.                 
  343.                 Validation:
  344.                     The upper byte of the PrintX[1] field must be the ID of the device 
  345.                         (kLQRefNum in OldAPIMessageIntf.h).
  346.                     
  347.                     The version of the print record must be current
  348.                         (oldIWLQPrintRecordVersion in Resources.h)
  349.                     
  350.                     (For new print records, we will validate all of the fields which are 
  351.                      public (e.g., paper size), not just these fields)
  352.                 
  353.     parameters:                
  354.                 hPrint                    print record to validate
  355.                 wasChanged                returns true if print record was invalid; false otherwise
  356.                 
  357.     returns:
  358.                 OSErr
  359.     
  360. ****************************************************************************************/
  361. OSErr SD_PrValidate(THPrint hPrint, Boolean *wasChanged)
  362. {
  363.     short        wDev;                        // device specific stuff in this word
  364.     Boolean    returnVal = true;        // initialize return value to "invalid"
  365.                                             //     Why is true == "invalid"? Nobody knows!
  366.     
  367.     // check the wDev.  The upper byte must be equal to kLQRefNum.  We get the
  368.     //  wDev, and shift wDev DOWN eight.
  369.         
  370.     wDev =  (*hPrint)->printX[1];
  371.     wDev >>= 8;                                // get just the device ID
  372.  
  373.  
  374.     // If the device id is equal, then check the version number of the print record.
  375.     //    Only if that is also equal to the current version, will we return false (valid).
  376.         
  377.     if (wDev == kLQRefNum)
  378.         if ( (*hPrint)->iPrVersion == oldIWLQPrintRecordVersion )
  379.             returnVal = false;
  380.             
  381.  
  382.     // If the print record is not valid, then return the default print record.
  383.     // Otherwise, update the print record, based on the application's calls
  384.     // to PrGeneral.
  385.  
  386.     if (returnVal)
  387.         PrintDefault(hPrint);
  388.     else
  389.         UpdatePrintRecord(hPrint);
  390.         
  391.     *wasChanged = returnVal;
  392.     
  393.     return(noErr);
  394. }
  395. /* SD_PrValidate */
  396.  
  397.  
  398. /****************************************************************************************
  399.  
  400.                             SD_ConvertPrintRecordTo
  401.                             
  402.     function:     
  403.                 SD_ConvertPrintRecordTo converts the fields of the print record for
  404.                 the device into the universal print record format.  
  405.                 
  406.     parameters:    
  407.                 hPrint        print record to convert to universal format
  408.     
  409.     returns:
  410.                 OSErr
  411.     
  412. ****************************************************************************************/
  413. OSErr SD_ConvertPrintRecordTo(THPrint hPrint)
  414. {
  415.     gxUniversalPrintRecordPtr    pUniv;
  416.     TPPrint                             pPrint;
  417.     short                                options = 0;
  418.  
  419.     pUniv = (gxUniversalPrintRecordPtr) *hPrint;
  420.     pPrint = *hPrint;
  421.     
  422.     // Convert paper feed settings (old and univ setting are switched)
  423.  
  424.     if ( pPrint->prStl.feed == oldPRECAutoFeed )
  425.         pUniv->feed = gxAutoFeed;
  426.     else
  427.         pUniv->feed = gxManualFeed;
  428.     
  429.     // Fix up the actualCopies field
  430.     pUniv->actualCopies = pPrint->prJob.iCopies;
  431.     
  432.     // Determine the new options field settings
  433.  
  434.     if ( TestBit(pPrint->prStl.wDev, kScrollBit) )
  435.         options |= gxBiggerPages;
  436.         
  437.     pUniv->options = options;
  438.  
  439.     
  440.     // Now determine the scaling factor, if any, and designate the proper dialog button that
  441.     // corresponds to the scaling factor.  The userCluster1 field specifies the dialog button.
  442.     
  443.     if ( TestBit(pPrint->prStl.wDev, k66PercentReducBit) )
  444.     {
  445.         pUniv->reduction = 66;
  446.         pUniv->userCluster1 = 1;
  447.     }
  448.     else 
  449.     if ( TestBit(pPrint->prStl.wDev, k33PercentReducBit) )
  450.     {
  451.         pUniv->reduction = 33;
  452.         pUniv->userCluster1 = 0;
  453.     }
  454.     else     //    T => No scaling being performed
  455.     {
  456.         pUniv->reduction = 100;
  457.         pUniv->userCluster1 = 2;
  458.     }
  459.     
  460.  
  461.     // Set the orientation properly
  462.  
  463.     if ( TestBit(pPrint->prStl.wDev, kPortraitBit) )
  464.         pUniv->orientation = gxPortraitOrientation;
  465.     else
  466.         pUniv->orientation = gxLandscapeOrientation;
  467.  
  468.  
  469.     // Determine the quality setting
  470.     
  471.     if ( TestBit(pPrint->prStl.wDev, kHighResBit) )    //    T => Print in best quality
  472.     {
  473.         pUniv->qualityMode = gxBestQuality;
  474.     }
  475.     else
  476.     if ( pPrint->prJob.bJDocLoop == spool )    //    T => Print with faster quality
  477.     {
  478.         pUniv->qualityMode = gxFasterQuality;
  479.     }
  480.     else    //    T => Print with draft quality
  481.         pUniv->qualityMode = gxDraftQuality;
  482.     
  483.     
  484.     // Set the first tray and remaining tray fields
  485.     
  486.     if ( (pPrint->printX[0] & 0x0003) > 0 )    //    T => A first tray has been specified
  487.     {
  488.         switch ( pPrint->printX[0] & 0x0003 )
  489.         {
  490.             case    tray1:    pUniv->firstTray = gxFirstTray;        break;
  491.             case    tray2:    pUniv->firstTray = gxSecondTray;        break;
  492.             case    tray3:    pUniv->firstTray = gxThirdTray;        break;
  493.             default:            pUniv->firstTray = gxFirstTray;        break;
  494.         }
  495.     }
  496.     else
  497.         pUniv->firstTray = gxFirstTray;
  498.  
  499.     if ( (pPrint->printX[0] & 0x000C) > 0 )    //    T => A remaining tray has been specified
  500.     {
  501.         switch ( pPrint->printX[0] & 0x000C )
  502.         {
  503.             case    tray1:    pUniv->remainingTray = gxFirstTray;    break;
  504.             case    tray2:    pUniv->remainingTray = gxSecondTray;    break;
  505.             case    tray3:    pUniv->remainingTray = gxThirdTray;    break;
  506.             default:            pUniv->remainingTray = gxFirstTray;    break;
  507.         }
  508.     }
  509.     else
  510.         pUniv->remainingTray = gxFirstTray;
  511.  
  512.     
  513.     // Set the headMotion field's value
  514.     
  515.     if ( TestBit(pPrint->prStl.wDev, kBiDirBit) )    //    T => Print in bidirectional mode
  516.     {
  517.         pUniv->headMotion = gxBidirectionalMotion;
  518.     }
  519.     else
  520.         pUniv->headMotion = gxUnidirectionalMotion;
  521.  
  522.         
  523.     // Always assign these fields explicit values to ensure they don't cause problems
  524.     
  525.     pUniv->coverPage         = gxNoCoverPage;
  526.     pUniv->saveFile         = gxNoFile;
  527.     
  528.     return(noErr);
  529. }
  530. /* SD_ConvertPrintRecordTo */
  531.  
  532.  
  533. /****************************************************************************************
  534.  
  535.                             SD_ConvertPrintRecordFrom
  536.                             
  537.     function:     
  538.                 SD_ConvertPrintRecordFrom converts the fields of the print record in 
  539.                 universal print record format into the print record format for the
  540.                 specific device. 
  541.                 
  542.     parameters:    
  543.                 hPrint        print record to convert to device specific format
  544.     
  545.     returns:
  546.                 OSErr
  547.     
  548. ****************************************************************************************/
  549. OSErr SD_ConvertPrintRecordFrom(THPrint hPrint)
  550. {
  551.     gxUniversalPrintRecordPtr    pUniv;
  552.     TPPrint                             pPrint;
  553.     short                                newWDev = kLQRefNum << 8;
  554.  
  555.     pUniv = (gxUniversalPrintRecordPtr) *hPrint;
  556.     pPrint = *hPrint;
  557.     
  558.     // Convert paper feed settings (old and univ setting are switched)
  559.  
  560.     if ( pUniv->feed == gxAutoFeed )
  561.         pPrint->prStl.feed = oldPRECAutoFeed;
  562.     else
  563.         pPrint->prStl.feed = oldPRECManualFeed;
  564.  
  565.  
  566.     // Fix up the actualCopies field
  567.     pPrint->prJob.iCopies = pUniv->actualCopies;
  568.     
  569.     
  570.     // Determine the new wDev flag settings
  571.     
  572.     if ( TestBit(pUniv->options, gxBiggerPages) )
  573.         newWDev |= kScrollBit;
  574.         
  575.     if (pUniv->headMotion == gxBidirectionalMotion)
  576.         newWDev |= kBiDirBit;
  577.         
  578.     switch( pUniv->userCluster1 )    //    Based on the scaling dialog button setting, set the scaling factor
  579.     {
  580.         case 2:        //    Full size
  581.             break;
  582.             
  583.         case 1:
  584.             newWDev |= k66PercentReducBit;
  585.             break;
  586.             
  587.         case 0:
  588.             newWDev |= k33PercentReducBit;
  589.             break;
  590.     }
  591.     
  592.     if (pUniv->orientation == gxPortraitOrientation)
  593.         newWDev |= kPortraitBit;
  594.  
  595.     if (pUniv->qualityMode == gxBestQuality)
  596.     {
  597.         newWDev |= kHighResBit;
  598.         pPrint->prJob.bJDocLoop = spool;
  599.     }
  600.     else
  601.     if (pUniv->qualityMode == gxFasterQuality)
  602.     {
  603.         pPrint->prJob.bJDocLoop = spool;
  604.     }
  605.     else    //    T => Draft quality
  606.     {
  607.         newWDev |= kDraftBit;
  608.         pPrint->prJob.bJDocLoop = draft;
  609.     }
  610.  
  611.     // set the bit to indicate SetResolution has been called, if the resolution is already 216
  612.     if ( pPrint->prInfo.iVRes == 216)
  613.         newWDev |= kResSetBit;
  614.  
  615.     // Update the wDev field and the printX[1] field (a copy of wDev)
  616.     pPrint->prStl.wDev = newWDev;
  617.     pPrint->printX[1] = newWDev;
  618.     
  619.     
  620.     // Fix up the tray settings
  621.     {
  622.         short        firstTrayNum = tray1;
  623.         short        remainingTrayNum = tray1;
  624.         
  625.         switch (pUniv->firstTray)
  626.         {
  627.             case    gxFirstTray:        firstTrayNum = tray1;        break;
  628.             case    gxSecondTray:        firstTrayNum = tray2;        break;
  629.             case    gxThirdTray:        firstTrayNum = tray3;        break;
  630.         }
  631.         
  632.         switch (pUniv->remainingTray)
  633.         {
  634.             case    gxFirstTray:        remainingTrayNum = tray1;    break;
  635.             case    gxSecondTray:        remainingTrayNum = tray2;    break;
  636.             case    gxThirdTray:        remainingTrayNum = tray3;    break;
  637.         }
  638.         
  639.         pPrint->printX[0] = (remainingTrayNum << 2) | firstTrayNum;
  640.     }
  641.  
  642.     // Initialize some of the remaining fields in the TPrXInfo structure. PrValidate will fill in the rest
  643.     
  644.     pPrint->prXInfo.bUlThick = 0;
  645.     pPrint->prXInfo.bUlOffset = 0;
  646.     pPrint->prXInfo.bUlShadow = 0;
  647.     pPrint->prXInfo.bXInfoX = 0;
  648.  
  649.     return(noErr);
  650. }
  651. /* SD_ConvertPrintRecordFrom */
  652.  
  653.  
  654. /****************************************************************************************
  655.  
  656.                             SD_PrintRecordToJob
  657.                             
  658.     function:     
  659.                 SD_PrintRecordToJob is called by the Printing Manager when a print record
  660.                 needs to be converted into a job.  This driver takes this opportunity to
  661.                 add two collection items to the job, namely the one which specifies the
  662.                 desired head motion and the users tray selection.
  663.                 
  664.     parameters:    
  665.                 hPrint        print record to convert to a job
  666.                 theJob        job reference to use in converting the print record
  667.     
  668.     returns:
  669.                 OSErr
  670.     
  671. ****************************************************************************************/
  672. OSErr SD_PrintRecordToJob(THPrint hPrint, gxJob theJob)
  673. {
  674.     OSErr        anErr;
  675.     
  676.     // First forward the message so the job is created
  677.     anErr = Forward_GXPrintRecordToJob(hPrint, theJob);
  678.     require(anErr == noErr, Forward_GXPrintRecordToJob);
  679.     
  680.     // Add the collection item which specifies the desired head motion
  681.     {
  682.         HeadMotionJobItem        theMotion;
  683.         
  684.         theMotion.direction = (!TestBit((*hPrint)->prStl.wDev, kBiDirBit)) ? doUnidirectional : doBidirectional;
  685.         
  686.         anErr = AddCollectionItem(    GXGetJobCollection(theJob), 
  687.                                             kDrvrCreatorType, 
  688.                                             kHeadMotionItemIndex, 
  689.                                             sizeof(HeadMotionJobItem),
  690.                                             &theMotion);
  691.         require(anErr == noErr, AddHeadMotion);
  692.     }
  693.     
  694.     
  695.     // Add the collection item which specifies the desired tray settings
  696.     {
  697.         TraySettingsJobItem        theTraySettings;
  698.         
  699.         theTraySettings.firstPageFromTray = (*hPrint)->printX[0] & 0x0003;
  700.         theTraySettings.remainingFromTray = ((*hPrint)->printX[0] & 0x000C) >> 2;
  701.         
  702.         anErr = AddCollectionItem(    GXGetJobCollection(theJob), 
  703.                                             kDrvrCreatorType, 
  704.                                             kTraySettingsItemIndex, 
  705.                                             sizeof(TraySettingsJobItem),
  706.                                             &theTraySettings);
  707.         require(anErr == noErr, AddTraySettings);
  708.     }
  709.  
  710.  
  711. /******* Clean-up *******/
  712.  
  713. AddHeadMotion:
  714. AddTraySettings:
  715. Forward_GXPrintRecordToJob:
  716.     return(anErr);
  717. }
  718. /* SD_PrintRecordToJob */